from datetime import datetime
from typing import List
import uuid

from pydantic import EmailStr
from sqlmodel import Field, Relationship, SQLModel, Text, create_engine


# Shared properties
class UserBase(SQLModel):
    email: EmailStr = Field(unique=True, index=True, max_length=255)
    is_active: bool = True
    is_superuser: bool = False
    full_name: str | None = Field(default=None, max_length=255)


# Properties to receive via API on creation
class UserCreate(UserBase):
    password: str = Field(min_length=8, max_length=40)


class UserRegister(SQLModel):
    email: EmailStr = Field(max_length=255)
    password: str = Field(min_length=8, max_length=40)
    full_name: str | None = Field(default=None, max_length=255)


# Properties to receive via API on update, all are optional
class UserUpdate(UserBase):
    email: EmailStr | None = Field(default=None, max_length=255)  # type: ignore
    password: str | None = Field(default=None, min_length=8, max_length=40)


class UserUpdateMe(SQLModel):
    full_name: str | None = Field(default=None, max_length=255)
    email: EmailStr | None = Field(default=None, max_length=255)


class UpdatePassword(SQLModel):
    current_password: str = Field(min_length=8, max_length=40)
    new_password: str = Field(min_length=8, max_length=40)


# Database model, database table inferred from class name
class User(UserBase, table=True):
    id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
    hashed_password: str
    items: list["Item"] = Relationship(back_populates="owner", cascade_delete=True)
    devices: list["Device"] = Relationship(back_populates="owner", cascade_delete=True)
    tasks: list["Task"] = Relationship(back_populates="owner", cascade_delete=True)


# Properties to return via API, id is always required
class UserPublic(UserBase):
    id: uuid.UUID


class UsersPublic(SQLModel):
    data: list[UserPublic]
    count: int


# Shared properties
class ItemBase(SQLModel):
    title: str = Field(min_length=1, max_length=255)
    description: str | None = Field(default=None, max_length=255)


# Properties to receive on item creation
class ItemCreate(ItemBase):
    pass


# Properties to receive on item update
class ItemUpdate(ItemBase):
    title: str | None = Field(default=None, min_length=1, max_length=255)  # type: ignore


# Database model, database table inferred from class name
class Item(ItemBase, table=True):
    id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
    owner_id: uuid.UUID = Field(
        foreign_key="user.id", nullable=False, ondelete="CASCADE"
    )
    owner: User | None = Relationship(back_populates="items")


# Properties to return via API, id is always required
class ItemPublic(ItemBase):
    id: uuid.UUID
    owner_id: uuid.UUID


class ItemsPublic(SQLModel):
    data: list[ItemPublic]
    count: int


# Generic message
class Message(SQLModel):
    message: str


# JSON payload containing access token
class Token(SQLModel):
    access_token: str
    token_type: str = "bearer"


# Contents of JWT token
class TokenPayload(SQLModel):
    sub: str | None = None


class NewPassword(SQLModel):
    token: str
    new_password: str = Field(min_length=8, max_length=40)


class Device(SQLModel, table=True):
    __tablename__ = "devices"
    id: int | None = Field(default=None, primary_key=True)
    hostname: str = Field(max_length=255)
    owner: User | None = Relationship(back_populates="devices")
    tasks: List['Task'] = Relationship(back_populates="device")
    user_id: uuid.UUID | None = Field(
        default=None, foreign_key="user.id", nullable=True
    )
    mac: str = Field(max_length=255)
    ip: str = Field(max_length=255)
    create_time: datetime = Field(default_factory=datetime.now)
    last_online: datetime = Field(default_factory=datetime.now)

class SpeechData(SQLModel,table=True):
    id: int | None = Field(default=None, primary_key=True)
    task_id:str = Field(max_length=255)
    language:str = Field(max_length=255,nullable=True)
    language_name:str = Field(max_length=255,nullable=True)
    create_time: datetime = Field(default_factory=datetime.now)
    project:str = Field(max_length=255,nullable=True)
    user:str = Field(max_length=255,nullable=True)
    content:str = Field(max_length=255,nullable=True)
    desc:str = Field(max_length=255,nullable=True)
    feedback:str = Field(max_length=255,nullable=True)
    dept:int = Field(default=1)

class ZentaoData(SQLModel,table=True):
    id: int | None = Field(default=None, primary_key=True)
    user:str = Field(max_length=255,nullable=True)
    project:str = Field(max_length=255,nullable=True)
    create_time: datetime = Field(default_factory=datetime.now)
    

class DevicePublic(SQLModel):
    id: int
    hostname: str
    mac: str
    ip: str
    create_time: datetime
    last_online: datetime
    owner: User | None

class DeviceListResponse(SQLModel):
    data: List[DevicePublic]
    count: int


class BatchExecuteScriptsReq(SQLModel):
    info: dict[str, str]
    scripts: List[str]


class Project(SQLModel, table=True):
    __tablename__ = "project"
    id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
    name: str = Field(max_length=255)
    tasks: List['Task'] = Relationship(back_populates="project", cascade_delete=True)
class Task(SQLModel,table=True):
    # {'create_time': 1754877353.9830658, 'device_id': 1, 'end_time': '', 'name': '本地执行', 'num': 1, 'overwrite': True, 'process': '未执行', 'result': False, 'start_time': 1754877353.9830658, 'task_hash': '8cd210bfbb0c89c8166ab5d2b156976eb9674280b46ab0464b2b7b97b9761130', 'user_id': -1}
    id: uuid.UUID = Field(default_factory=uuid.uuid4,primary_key=True)
    name: str
    owner :User|None = Relationship(back_populates="tasks")
    user_id: uuid.UUID|None = Field(default=None, foreign_key="user.id",nullable=True)
    device:Device = Relationship(back_populates="tasks")
    device_id: int = Field(default=None, foreign_key="devices.id")
    status: int|None = Field(default=0)
    process:str|None
    create_time: datetime|None = Field(default_factory=datetime.now,nullable=True)
    end_time: datetime|None = Field(default_factory=None,nullable=True)
    result:bool|None = Field(default=False,nullable=True)
    task_hash: str
    records: List['Record'] = Relationship(back_populates="task", cascade_delete=True)
    project_id: uuid.UUID | None = Field(default=None, foreign_key="project.id", nullable=True)
    project: Project | None = Relationship(back_populates="tasks")

class TaskPublic(SQLModel):
    id: uuid.UUID
    name: str
    user_id: uuid.UUID | None
    device_id: int
    status: int | None
    process: str | None
    create_time: datetime | None
    end_time: datetime | None
    result: bool | None
    task_hash: str
    # 包含关联的用户和设备信息
    owner: UserBase | None = None
    device: Device | None = None
    project: Project | None = None

class TaskDetail(TaskPublic):
    records: List['Record'] = Field(default_factory=list)

class TaskListResponse(SQLModel):
    data: List[TaskPublic]
    count: int

class Record(SQLModel,table=True):
    id : uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)
    script_hash: str = Field(max_length=255)
    name:str = Field(max_length=255)
    path: str
    task_id: uuid.UUID | None = Field(default=None, foreign_key="task.id", nullable=True)
    task: Task | None = Relationship(back_populates="records")
    script : str |None = Field(default=None)
    log : str | None = Field(default=None)
    result: bool | None = Field(default=None)
    start_time: datetime | None = Field(default_factory=datetime.now, nullable=True)
    end_time: datetime | None = Field(default=None, nullable=True)

class ProjectPublic(SQLModel):
    id: uuid.UUID | None
    name: str


class ProjectsResponse(SQLModel):
    data: List[ProjectPublic]
    count: int

